package fr.upmc.i3s.upmcontact.tools;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

public class BitmapFactoryAdapter {
	
	private static final String TAG = "BitmapFactoryAdapter";
	
	//////////////
	// DECODERS //
	//////////////
	
	public static Bitmap decodeResource(Context context, int id, int requiredSize) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(context.getResources(), id, options);
		int scale=1;
		while(options.outWidth/scale/2>=requiredSize && options.outHeight/scale/2>=requiredSize) {
			scale*=2;
		}
		BitmapFactory.Options options2 = new BitmapFactory.Options();
		options2.inSampleSize=scale;
		return BitmapFactory.decodeResource(context.getResources(), id, options2);
	}
	
	public static Bitmap decodeFile(String filePath, int requiredSize) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filePath, options);
		int scale=1;
		while(options.outWidth/scale/2>=requiredSize && options.outHeight/scale/2>=requiredSize) {
			scale*=2;
		}
		BitmapFactory.Options options2 = new BitmapFactory.Options();
		options2.inSampleSize=scale;
		return BitmapFactory.decodeFile(filePath, options2);
	}
	
	public static Bitmap decodeUri(Uri uri, int requiredSize) {
		return decodeFile(uri.getPath(), requiredSize);
	}
	
	@Deprecated
	public static Bitmap getBitmapFromUri(Context context, Uri uri) {
		try {
			return MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
		} catch (FileNotFoundException e) {
			Log.e(TAG, "FileNotFoundException : ",e);
			return null;
		} catch (IOException e) {
			Log.e(TAG, "IOException : ",e);
			return null;
		} 
	}
	
	
	  ////////////////
	 // CONVERTERS //
	////////////////
	
	public static Bitmap getBitmapFromByteArray(byte[] data) {
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}
	
	public static byte[] getByteArrayFromFile(String filePath, int requiredSize, int quality) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		BitmapFactoryAdapter.decodeFile(filePath, requiredSize).compress(Bitmap.CompressFormat.JPEG, quality, stream);
		return stream.toByteArray();
	}
	
	public static Bitmap resize(Bitmap bm, int requiredSize) {
		int newW = requiredSize, newH = requiredSize;
		if(bm.getHeight() > bm.getWidth()) {
			newH = (bm.getHeight()*requiredSize) / bm.getWidth();
		} else if (bm.getHeight() < bm.getWidth()) {
			newW = (bm.getWidth()*requiredSize) / bm.getHeight();
		}
		return Bitmap.createScaledBitmap(bm, newW, newH, false);
	}
	
//	public static byte[] getByteArrayFromBitmap(Bitmap bm) {
//		int bytes = bm.getByteCount();
//		ByteBuffer buffer = ByteBuffer.allocate(bytes);
//		bm.copyPixelsToBuffer(buffer);
//		return buffer.array(); 
//	}
	
	public static byte[] getByteArrayFromFile(File f) {
		try {
			return FileUtils.readFileToByteArray(f);
		} catch (IOException e) {
			Log.e(TAG, "IOException : ",e);
			return null;
		}
	}
	
	
	  /////////////
	 // STORAGE //
	/////////////
	
	public static String saveByteArrayOnExternalStorage(byte[] data, String path, String filename) {
		try {
			FileOutputStream fos = new FileOutputStream(path+filename);
	        fos.write(data);
	        fos.close();
	        return path+filename;
		} catch (IOException e1) {
			Log.e(TAG, "IOException : ", e1);
			return null;
		}
	}
	
	
	  //////////////////
	 // CLEAR AND GC //
	//////////////////
	
	public static void clearBitmap(Bitmap bm) {
		bm.recycle();
		System.gc();
	}

}
